﻿using System;
using System.Windows.Forms;
using Kyoh.App.Crawler.Contents;
using Kyoh.Lib.WinForms;
using Kyoh.App.Crawler.Plugin;

namespace Kyoh.App.Crawler
{
    partial class PreferenceForm : Form
    {
        private Parsers _parsers;
        private Redirects _redirects;
        private Seekers _seekers;
        private Pickers _pickers;

        public PreferenceForm(Parsers parsers, Redirects redirects, Seekers seekers, Pickers pickers)
        {
            _parsers = parsers;
            _redirects = redirects;
            _seekers = seekers;
            _pickers = pickers;

            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            InitValue();
            foreach (TabPage tab in tabControl1.TabPages)
                foreach(Control control in tab.Controls)
                    control.Parent = preferencePanel;
            tabControl1.Visible = false;
            base.OnLoad(e);
        }

        #region 設定の読み込みと反映

        public const int MillisecondPerMinute = 60000;
        public const int MillisecondPerSecond = 1000;

        public void InitValue()
        {
            parsersPluginManagerControl.DataSource = _parsers;
            redirectsPluginManagerControl.DataSource = _redirects;
            seekersPluginManagerControl.DataSource = _seekers;
            pickersPluginManagerControl.DataSource = _pickers;

            #region Action 設定項目群
            downloadPathEditor.Path = Properties.Settings.Default.DownloadPath;
            downloadPathEditor.Validate();

            seekIntervalLabeledTrackBar.Value = Properties.Settings.Default.SeekInterval / MillisecondPerMinute;
            seekParallelismLabeledTrackBar.Value = Properties.Settings.Default.SeekParallelism;
            downloadIntervalLabeledTrackBar.Value = Properties.Settings.Default.DownloadInterval / MillisecondPerSecond;
            downloadParallelismLabeledTrackBar.Value = Properties.Settings.Default.DownloadParallelism;

            loaderDefaultBehaviorComboBox.SelectedValue = Properties.Settings.Default.LoaderDefaultBehavior;
            #endregion

            #region Window 設定項目群
            closingBehaviorComboBox.SelectedValue = Properties.Settings.Default.FormClosingBehavior;
            minimizeToNotificationAreaCheckBox.Checked = Properties.Settings.Default.MinimizeToNotifier;
            memorizeWindowSizeCheckBox.Checked = Properties.Settings.Default.MemorizeWindowSize;
            thumbnailSizeNumericUpDown.Value = Properties.Settings.Default.LoaderRowSize;
            #endregion

            #region Commands 設定項目群

            // コマンド挿入メニューの初期化
            insertCommandTermsContextMenuStrip.Items.Clear();
            foreach (var kv in Properties.Settings.GetParams(null))
            {
                var item = new ToolStripMenuItem(string.Format(@"{{{0}}} {1}", kv.Key, kv.Value))
                               {Tag = string.Intern(kv.Key)};
                item.Click += (sender, e) => InsertCommand(sender as ToolStripMenuItem);
                insertCommandTermsContextMenuStrip.Items.Add(item);
            }

            openContentArgsTextBox.Text = Properties.Settings.Default.OpenFileCommandArgs;
            openContentCommandTextBox.Text = Properties.Settings.Default.OpenFileCommand;
            openContentDirectoryArgsTextBox.Text = Properties.Settings.Default.OpenDirectoryCommandArgs;
            openContentDirectoryCommandTextBox.Text = Properties.Settings.Default.OpenDirectoryCommand;
            openPageArgsTextBox.Text = Properties.Settings.Default.OpenPageCommandArgs;
            openPageCommandTextBox.Text = Properties.Settings.Default.OpenPageCommand;

            #endregion
        }

        private TextBox _insertCommandTargetTextBox;
        private void ShowInsertCommandMenu(TextBox textBox, Button button)
        {
            if (button == null)
                return;
            _insertCommandTargetTextBox = textBox;
            insertCommandTermsContextMenuStrip.Show(button, button.Width, 0);
        }

        private void InsertCommand(ToolStripMenuItem item)
        {
            if (item == null)
                return;

            if (_insertCommandTargetTextBox != null)
                _insertCommandTargetTextBox.SelectedText = "{" + item.Tag + "}";
            _insertCommandTargetTextBox = null;
        }

        public void SaveValue()
        {
            #region Action 設定項目群
            if (downloadPathEditor.Valid == PathEditor.PathValidation.Valid)
                Properties.Settings.Default._DownloadPath = downloadPathEditor.Path;

            Properties.Settings.Default.SeekInterval = seekIntervalLabeledTrackBar.Value * MillisecondPerMinute;
            Properties.Settings.Default.SeekParallelism = seekParallelismLabeledTrackBar.Value;
            Properties.Settings.Default.DownloadInterval = downloadIntervalLabeledTrackBar.Value * MillisecondPerSecond;
            Properties.Settings.Default.DownloadParallelism = downloadParallelismLabeledTrackBar.Value;

            Properties.Settings.Default.LoaderDefaultBehavior = (LoaderDefaultBehavior)loaderDefaultBehaviorComboBox.SelectedValue;
            #endregion

            #region Window 設定項目群
            Properties.Settings.Default.FormClosingBehavior = (FormClosingBehavior)closingBehaviorComboBox.SelectedValue;
            Properties.Settings.Default.MinimizeToNotifier = minimizeToNotificationAreaCheckBox.Checked;
            Properties.Settings.Default.MemorizeWindowSize = memorizeWindowSizeCheckBox.Checked;
            Properties.Settings.Default.LoaderRowSize = thumbnailSizeNumericUpDown.Value;
            #endregion

            #region Commands 設定項目群

            Properties.Settings.Default.OpenFileCommandArgs = openContentArgsTextBox.Text;
            Properties.Settings.Default.OpenFileCommand = openContentCommandTextBox.Text;
            Properties.Settings.Default.OpenDirectoryCommandArgs = openContentDirectoryArgsTextBox.Text;
            Properties.Settings.Default.OpenDirectoryCommand = openContentDirectoryCommandTextBox.Text;
            Properties.Settings.Default.OpenPageCommandArgs = openPageArgsTextBox.Text;
            Properties.Settings.Default.OpenPageCommand = openPageCommandTextBox.Text;

            #endregion
        }

        #endregion

        #region 設定画面の切り替え

        private Control SelectControl(TreeNode node)
        {
            if (node == null)
                return null;

            var controlName = node.Tag as string;
            if (string.IsNullOrEmpty(controlName))
                return null;

            if (!preferencePanel.Controls.ContainsKey(controlName))
                return null;

            return preferencePanel.Controls[controlName];
        }

        private Control _visibleControl;

        private void PreferenceMenuTreeViewBeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            var control = SelectControl(e.Node);
            if (control == null || control.Enabled == false)
            {
                e.Cancel = true;
            }
        }

        private void PreferenceMenuTreeViewAfterSelect(object sender, TreeViewEventArgs e)
        {
            var control = SelectControl(e.Node);
            if (control == null || control.Enabled == false)
                return;
            if (_visibleControl != null)
                _visibleControl.Visible = false;
            control.Visible = true;
            _visibleControl = control;
        }

        #endregion

        private void OkButtonClick(object sender, EventArgs e)
        {
            SaveValue();
        }

        private void OpenContentCommandButtonClick(object sender, EventArgs e)
        {
            ShowInsertCommandMenu(openContentCommandTextBox, sender as Button);
        }

        private void OpenContentArgsButtonClick(object sender, EventArgs e)
        {
            ShowInsertCommandMenu(openContentArgsTextBox, sender as Button);
        }

        private void OpenContentDirectoryCommandButtonClick(object sender, EventArgs e)
        {
            ShowInsertCommandMenu(openContentDirectoryCommandTextBox, sender as Button);
        }

        private void OpenContentDirectoryArgsButtonClick(object sender, EventArgs e)
        {
            ShowInsertCommandMenu(openContentDirectoryArgsTextBox, sender as Button);
        }

        private void OpenPageCommandButtonClick(object sender, EventArgs e)
        {
            ShowInsertCommandMenu(openPageCommandTextBox, sender as Button);
        }

        private void OpenPageArgsButtonClick(object sender, EventArgs e)
        {
            ShowInsertCommandMenu(openPageArgsTextBox, sender as Button);
        }

        private void PluginsSelectionChanged(object sender, EventArgs e)
        {
            var manager = sender as PluginManagerControl;
            if (manager == null)
                return;
            manager.PreferenceEnabled = (manager.CurrentPreference != null);
        }

        private void PluginManagerControl_Preference(object sender, EventArgs e)
        {
            var manager = sender as PluginManagerControl;
            if (manager == null)
                return;
            var plugin = manager.CurrentPlugin;
            if (plugin != null)
            {
                pluginPreference.Plugin = plugin;
                if (_visibleControl != null)
                    _visibleControl.Visible = false;
                pluginPreference.Visible = true;
                preferenceMenuTreeView.Enabled = false;
            }
        }

        private void PluginPreferenceHide(object sender, EventArgs e)
        {
            if (_visibleControl != null)
                _visibleControl.Visible = true;
            pluginPreference.Visible = false;
            preferenceMenuTreeView.Enabled = true;
        }
    }
}